/*******************************************************************************
  * 文件：Hardware.c
  * 作者：zyz
  * 版本：v1.0.0
  * 日期：2017-08-03
  * 说明：硬件相关
*******************************************************************************/

/* 头文件 *********************************************************************/
#include "Hardware.h"
#include "Hardware_Timer.h"
#include "Hardware_Uart.h"
#include "Hardware_WDT.h"
#include "Hardware_IO.h"
#include "Hardware_PWM.h"
#include "lib_config.h"

/* 宏定义 *********************************************************************/
// 临界区堆栈深度
#define u8CRITICAL_STACK_MAX_DEPTH    ((U8) 64)

/* 类型定义 *******************************************************************/
/* 变量定义 *******************************************************************/
static U8 u8CriticalStackPointer = 0;                         // 临界区堆栈指针
static U32 au32CriticalStack[u8CRITICAL_STACK_MAX_DEPTH];    // 临界区堆栈数组

/* 函数声明 *******************************************************************/
/* 函数定义 *******************************************************************/

/*******************************************************************************
  * 函数名：Hardware_InitPLL
  * 功  能：锁相环初始化
  * 参  数：无
  * 返回值：无
  * 说  明：选择外部晶振为时钟输入，PLL倍频至48Mhz
*******************************************************************************/
static void Hardware_InitPLL(void)
{
    extern uint32_t SystemCoreClock;

    SystemClockSelect(CLK_SEL_HRC);
    PLLClock_Config(ENABLE, SCU_PLL_HRC, SCU_PLL_48M, ENABLE);//PLL enable ,sys_clk:48Mhz
    SystemCoreClock = 48000000;
}

/*******************************************************************************
  * 函数名：Hardware_Init
  * 功  能：硬件初始化
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Hardware_Init(void)
{
    Hardware_InitPLL();      // PLL倍频48Mhz
//    Hardware_InitWDT();      // 初始化看门狗
    Hardware_InitIO();       // 初始化IO
    Hardware_InitTimer();    // 初始化定时器
    Hardware_InitUart();     // 初始化串口
    Hardware_PWM_Init();     // 初始化PWM
    Hardware_DelayUS(1000);  // 延时1ms
}

/*******************************************************************************
  * 函数名：Hardware_SystemReset
  * 功  能：系统复位
  * 参  数：无
  * 返回值：无
  * 说  明：使用软件复位
*******************************************************************************/
void Hardware_SystemReset(void)
{
    NVIC_SystemReset();
}

/*******************************************************************************
  * 函数名：Hardware_DisableInterrupt
  * 功  能：关闭中断
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Hardware_DisableInterrupt(void)
{
    __disable_irq();
}

/*******************************************************************************
  * 函数名：Hardware_EnableInterrupt
  * 功  能：打开中断
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Hardware_EnableInterrupt(void)
{
    __enable_irq();
}

/*******************************************************************************
  * 函数名：Hardware_EnterCritical
  * 功  能：进入临界区
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/             
void Hardware_EnterCritical(void)
{
    // 保存中断状态
    au32CriticalStack[u8CriticalStackPointer] = __get_PRIMASK();
    // 关中断
    __disable_irq();
    // 更新堆栈指针
    u8CriticalStackPointer++;
}

/*******************************************************************************
  * 函数名：Hardware_ExitCritical
  * 功  能：退出临界区
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Hardware_ExitCritical(void)
{   
    // 更新堆栈指针
    u8CriticalStackPointer--;
    // 恢复中断状态
    __set_PRIMASK(au32CriticalStack[u8CriticalStackPointer]);
}

/*******************************************************************************
  * 函数名：Hardware_DelayUS
  * 功  能：延时微秒
  * 参  数：U16 u16Num - 微秒数
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Hardware_DelayUS(U16 u16Num)
{
    volatile U16 u16Cnt = u16Num;

    // 延时
    while(u16Cnt--)
    {
        // 48M，48个nop约为1us
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
    }
}

/*******************************************************************************
  * 函数名：Hardware_DelayMs
  * 功  能：延时毫秒
  * 参  数：U32 u32Ms - 毫秒
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void Hardware_DelayMS(U32 u32Ms)
{
    volatile U32 u32Count = u32Ms;

    while(u32Count--)
    {
        Hardware_RestartWDT();
        Hardware_DelayUS(1000);
    }
}
/***************************** 文件结束 ***************************************/
